/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */

package jp.ize.ux.components;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.UXController;
import jp.ize.ux.UXInteraction;
import jp.ize.ux.interactions.UXGeneralInteraction;
import jp.ize.ux.states.UXTableState;
import jp.ize.ux.states.UXBasicState;
import jp.ize.ux.geom.UXSize;
// }}}
// {{{ class UXHeaderCell extends UXCell
class UXHeaderCell extends UXCell
{
	// {{{ public function new( item : UXObject ) 
	/**
	* コンストラクタ
	*/
	public function new( item : UXObject ) 
	{
		super( item );
	}
	// }}}
}
// }}}
// {{{ class UXTableViewState extends UXTableState
class UXTableViewState extends UXTableState
{
	// {{{ public var activeCell(default, default) : UXCell;
	/**
	 * アクティブ状態のセルです。通常はnullです。
	 */
	public var activeCell(default, default) : UXCell;
	// }}}
	// {{{ public var size(default, default) : UXSize;
	/**
	 * テーブルのサイズを指定します
	 */
	public var size(default, default) : UXSize;
	// }}}
	// {{{ public var headers(default, default) : Array<UXCell>
	/**
	 * 左から順番に表示されるヘッダーの配列です。colsの値と配列の要素の数は一致している必要があります。
	 */
	public var headers(default, default) : Array<UXCell>;
	// }}}
	// {{{ public var items(default, default) : Array<Array<UXCell>>;
	/**
	 * 要素を保持する配列です。
	 */
	public var items(default, default) : Array<Array<UXCell>>;
	// }}}
	// {{{ public function new( size:UXSize, rows:Int, cols:Int )
	/**
	 * コンストラクタ。
	 *
	 * @param size: テーブルのサイズを指定します。
	 * @param rows: 行数を指定します。
	 * @param cols: 列数を指定します。
	 */
	public function new( size:UXSize, rows:Int, cols:Int )
	{
		super( rows, cols );
		this.size = size;
		items = new Array();
		for ( i in 0...rows ) {
			var ary:Array<UXCell> = new Array();
			for ( j in 0...cols ) {
				ary.push( null );
			}
			items.push(ary);
		}
	}
	// }}}
}
// }}}

// {{{ class UXTable extends UXComponent<UXTableViewState>
/**
 * UXTable クラス
 * テーブル上にコンポーネントを配置できるコンポーネント
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id$<br>
 */
class UXTable extends UXComponent<UXTableViewState>
{
	// {{{ properties
	// {{{ public var rowIndex:Int;
	/**
	* 現在指し示す行のインデックスです。
	*/
	public var rowIndex:Int;
	// }}}
	// {{{ public var colIndex:Int;
	/**
	* 現在指し示す列のインデックスです。
	*/
	public var colIndex:Int;
	// }}}
	// }}}
	// {{{ public function new( size:UXSize, rows:Int, cols:Int )
	/**
	 * コンストラクタです。テーブルのサイズと行数と列数を指定する必要があります。
	 *
	 * @param size: テーブルのサイズを指定します。
	 * @param rows: 行数を指定します。
	 * @param cols: 列数を指定します。
	 */
	public function new( size:UXSize, rows:Int, cols:Int )
	{
		state = new UXTableViewState( size, rows, cols );
		state.target = this;
		state.cyclic = true;
		ctrl = new UXController<UXTableViewState>( state );
		ctrl.addInteraction( new UXTableCellClickInteraction() );
		ctrl.addInteraction( new UXTableCellRollOverInteraction() );
		ctrl.addInteraction( new UXTableCellRollOutInteraction() );
		super( ctrl );
		rowIndex = 0;
		colIndex = 0;
	}
	// }}}
	// {{{ public function setBackground( back : UXObject ) : Void
	/**
	 * 背景となるオブジェクトを設定できます。
	 */
	public function setBackground( back : UXObject ) : Void
	{
	}
	// }}}
	// {{{ public function addUXChild( c : UXObject ) : Void
	/**
	 * addChild オーバーライドメソッドです。引数として受け取った子オブジェクトを追加し、
	 * このコンポーネントの状態やコントーラーに反映させます。
	 */
	public override function addUXChild( c : UXObject ) : Void
	{
		super.addUXChild( c );
		state.children.push( c );
		ctrl.addUXChild( c );
	}
	// }}}
	// {{{ public function removeUXChild( c : UXObject ) : Void
	/**
	 * removeChild オーバーライドメソッドです。引数として受け取った子オブジェクトを削除し、
	 * このコンポーネントの状態やコントローラーに反映させます。
	 */
	public override function removeUXChild( c : UXObject ) : Void
	{
		super.removeUXChild(c);
	}
	// }}}
	// {{{ public function getItem( i : Int, j : Int ) : Null<UXCell>
	/**
	 * (行, 列)の順番で指定された位置のアイテムを取得します。存在しない場合はnullが返されます。　
	 */
	public function getItem( i : Int, j : Int ) : Null<UXCell>
	{
		if ( i>=0 && i<state.rows && j>=0 && j<state.cols ) {
			return state.items[i][j];
		} else {
			return null;
		}
	}
	// }}}
	// {{{ public function setItem( i : int; j : Int, item : UXCell )
	/**
	 * (行. 列)の順番で指定された位置に指定されたアイテムを配置します。その位置に既にアイテムが存在する場合には、
	 * 上書きされます。(行, 列)の位置が存在しない場合にはなにもしません。
	 */
	public function setItem( i : Int, j : Int, item : UXCell )
	{
		if ( i>=0 && i<state.rows && j>=0 && j<state.cols ) {
			var me = this;
			item.state.row = i;
			item.state.col = j;
			state.items[i][j] = item;
			addUXChild( item );
			item.ctrl.getInteraction("Click").addAct( function(s){
				me.state.activeCell = cast(s.target,UXCell);
				me.ctrl.trigger("CellClick");
			});
			item.ctrl.getInteraction("RollOver").addAct( function(s){
				me.state.activeCell = cast(s.target,UXCell);
				me.ctrl.trigger("CellRollOver");
			});
			item.ctrl.getInteraction("RollOut").addAct( function(s){
				me.state.activeCell = cast(s.target,UXCell);
				me.ctrl.trigger("CellRollOut");
			});
		}
	}
	// }}}	
	// {{{ public function addItem( item : UXCell )
	/**
	* 順番に指定されたアイテムを追加します。
	* 現在の rowIndex, colIndex の指す位置に配置します。
	* 追加後は、rowIndex,colIndexはそれぞれ次の位置を指します。
	* 右から左、上から下の順番で追加されます。（論理配列上の位置）
	* 左下まで行った後は、rowIndex, colIndex は 0,0 に初期化されます。
	* その後は同様の順番で上書きされることになります。
	*/
	public function addItem( item : UXCell )
	{
		setItem( rowIndex, colIndex, item );
		colIndex++;
		if ( colIndex>=state.cols ) {
			colIndex = 0;
			rowIndex++;
			if ( rowIndex>=state.rows ) {
				rowIndex = 0;
			}
		}
	}
	// }}}	
	// {{{ public function update( updator : UXTableState -> Void ) : Void
	/**
	 * このコンポーネントの状態を直接変更するメソッドです。状態のどんな操作も可能になるので、
	 * このメソッドの使用には注意が必要です。
	 */
	public function update( updator : UXTableState -> Void ) : Void
	{
		updator( state );
	}
	// }}}
}
// }}}

// {{{ class UXTableCellClickInteraction extends UXGeneralInteraction<UXTableViewState>
/**
 * UXTableCellClickInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXTableCellClickInteraction extends UXGeneralInteraction<UXTableViewState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("CellClick");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXTableCellRollOverInteraction extends UXGeneralInteraction<UXTableViewState>
/**
 * UXTableCellRollOverInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXTableCellRollOverInteraction extends UXGeneralInteraction<UXTableViewState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("CellRollOver");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXTableCellRollOutInteraction extends UXGeneralInteraction<UXTableViewState>
/**
 * UXTableCellRollOutInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXTableCellRollOutInteraction extends UXGeneralInteraction<UXTableViewState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("CellRollOut");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
